﻿using System;
using System.Data;
using System.Data.OleDb;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

/// <summary>
/// </summary>
public class PlayoffRounds
{
    //public static readonly int[] Scores = new int[] { 100, 75, 50, 40, 35, 30, 25, 20, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    private List<PlayoffRound> _Rounds;
    public List<PlayoffRound> Rounds
{
  get { return _Rounds; }
  set { _Rounds = value; }
}

    public PlayoffRounds(List<PlayoffRound> p_Rounds){
        this._Rounds = p_Rounds; 
    }
  
    public PlayoffRounds() {
        this.Rounds = new List<PlayoffRound>(); 
    }

    private static Int64 RandomNumber(int min, int max)
    {
        Random random = new Random();
        return (Int64)random.Next(min, max);
    }

    public static void GenerateRandomPlayOffScoreValues()
    {
        try
        {
            ptss serviceptss = new ptss();
            string error;

            List<Tournament> Tours = Tournament.getAvailableTournaments();

            foreach (Tournament iTour in Tours)
            {
                DataTable oDataTable = DataBase.dt("SELECT Pk_Tournament,Fk_Machine,Round_Number,Fk_Player,MachineScore,Is_Joker,PlayInPosition,Player_Nick,Fk_Player_Zone,Machine_Acron,PlayerNumber,Machine_Number FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + iTour.Pk_Tournament.ToString() + " ORDER BY PlayerNumber ASC, Machine_Number ASC, Round_Number ASC");

                foreach (DataRow iRow in oDataTable.Rows)
                {
                    if (Int64.Parse(iRow["MachineScore"].ToString()) < 0)
                    {
                       
                        bool res = serviceptss.InsertPlayerScoreSimple(Int32.Parse(iRow["Pk_Tournament"].ToString()),
                                                                       Int32.Parse(iRow["Fk_Player"].ToString()),
                                                                       Int32.Parse(iRow["Fk_Machine"].ToString()),
                                                                       RandomNumber(1, 100000),
                                                                       false,
                                                                       false);
                    }
                }
            }
        }
        catch (Exception Ex)
        {

        }

    }

    public PlayoffRounds(int p_Pk_Tournament)
    {
        try
        {
            DataTable oDataTable = DataBase.dt("SELECT Pk_Tournament,Fk_Machine,Round_Number,Fk_Player,MachineScore,Is_Joker,PlayInPosition,Player_Nick,Fk_Player_Zone,Machine_Acron,PlayerNumber,Machine_Number FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " ORDER BY PlayerNumber ASC, Machine_Number ASC, Round_Number ASC");
            this.Rounds = new List<PlayoffRound>();
            foreach (DataRow iRow in oDataTable.Rows)
            {
                PlayoffRound oPlayoffRound = new PlayoffRound(Int32.Parse(iRow["Pk_Tournament"].ToString()),
                                                              Int32.Parse(iRow["Fk_Player"].ToString()),
                                                              iRow["Player_Nick"].ToString(),
                                                              Int32.Parse(iRow["Round_Number"].ToString()),
                                                              Int32.Parse(iRow["Fk_Player_Zone"].ToString()),
                                                              Int32.Parse(iRow["Fk_Machine"].ToString()),
                                                              iRow["Machine_Acron"].ToString(),
                                                              Int32.Parse(iRow["Machine_Number"].ToString()),
                                                              Int32.Parse(iRow["PlayInPosition"].ToString()),
                                                              Int64.Parse(iRow["MachineScore"].ToString()),
                                                              Int32.Parse(iRow["PlayerNumber"].ToString()),
                                                              Boolean.Parse(iRow["Is_Joker"].ToString()));



                this.Rounds.Add(oPlayoffRound);

            }
        }
        catch (Exception Ex)
        {

        }
    }

    public static Boolean InsertScores(int p_Pk_Tournament, int p_Pk_Player, int p_Pk_Machine, Int64 p_Score, Boolean IsQualify, Boolean IsJoker, out string Error) {
        OleDbConnection objConnection = new OleDbConnection();
        OleDbConnection objConnection2 = new OleDbConnection();
        Error = "None";
        try
            {

                try
                {
                    objConnection2 = DataBase.GetConnection();
                    objConnection2.Open();
                    OleDbCommand objCommand2 =
                        new OleDbCommand("INSERT INTO Log (DateAndTime,PK_Tournament,PK_Player,PK_Machine,Score,IsQualify,IsJoker) VALUES ('" +
                        //new OleDbCommand("INSERT INTO Log (DateTime,PK_Tournament,PK_Player,PK_Machine,Score,IsQualify,IsJoker) VALUES ('" +                                          
                                          DateTime.Now.ToString() + "'," +                 
                                          p_Pk_Tournament.ToString() + "," +
                                          p_Pk_Player.ToString() + "," +
                                          p_Pk_Machine.ToString() + "," +
                                          p_Score.ToString() + "," +
                                          IsQualify.ToString() + "," +
                                          IsJoker.ToString() +")", objConnection2);

                    objCommand2.ExecuteNonQuery();

                }
                catch (Exception Ex )
                {
                    Error = Ex.ToString(); 
                    string Exa = Ex.ToString(); 
                }  

                if (IsQualify == false)
                {

                  
                     DataTable oDataTable = DataBase.dt("SELECT MachineScore FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " and Fk_Machine=" + p_Pk_Machine.ToString() + " and Fk_Player=" + p_Pk_Player.ToString());
                   
                   

                    if (oDataTable.Rows.Count ==1)
                    {
                        if (IsJoker == true && Int64.Parse(oDataTable.Rows[0]["MachineScore"].ToString()) <  p_Score)
                        { 
                            //Solo actualizamos si es mejor
                            objConnection = DataBase.GetConnection();
                            OleDbCommand objCommand = new OleDbCommand("UPDATE PlayOffsTournamentRounds set Is_Joker=true,MachineScore=" + p_Score.ToString() + " WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " and Fk_Machine=" + p_Pk_Machine.ToString() + " and Fk_Player=" + p_Pk_Player.ToString(), objConnection);
                            objConnection.Open();
                            objCommand.ExecuteNonQuery();    
                        }else{
                            objConnection = DataBase.GetConnection();
                            if (p_Score == -1)
                            {
                                OleDbCommand objCommand = new OleDbCommand("UPDATE PlayOffsTournamentRounds set MachineScore=" + p_Score.ToString() + ",Is_Joker=false WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " and Fk_Machine=" + p_Pk_Machine.ToString() + " and Fk_Player=" + p_Pk_Player.ToString(), objConnection);
                                objConnection.Open();
                                objCommand.ExecuteNonQuery();
                            }
                            else if(IsJoker == false) {
                               OleDbCommand objCommand = new OleDbCommand("UPDATE PlayOffsTournamentRounds set MachineScore=" + p_Score.ToString() + " WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " and Fk_Machine=" + p_Pk_Machine.ToString() + " and Fk_Player=" + p_Pk_Player.ToString(), objConnection);
                               objConnection.Open();
                               objCommand.ExecuteNonQuery();
                            }
                            
                        }
                        return true;
                    }
                    else
                    {
                        Error = "This player not have results, or not have assigned this machine, or not promoted to playoffs";
                        return false;
                    }

                }
                else
                {
                    Error = "Imposible error";
                    return false;
                }
    }
    catch (Exception Ex)
    {
        Error = Ex.ToString(); 
        return false;
    }
    finally
    {
        objConnection.Close();
        objConnection2.Close();
    } 
    }

    public static Int64 GetScore(int p_Pk_Tournament, int p_Pk_Player, int p_Pk_Machine, Boolean IsQualify)
    {
        OleDbConnection objConnection = new OleDbConnection();
        try
        {
            if (IsQualify == true)
            {

                DataTable oDataTable = DataBase.dt("SELECT MachineScore FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " and Fk_Machine=" + p_Pk_Machine.ToString() + " and Fk_Player=" + p_Pk_Player.ToString());

                if (oDataTable.Rows.Count == 1)
                {
                    return Int64.Parse(oDataTable.Rows[0]["MachineScore"].ToString());
                    
                }
                else
                {
                   return -2;
                }

            }
            else
            {
                return -2;
            }
        }
        catch (Exception Ex)
        {
            return -2;
        }
    }

    public static Boolean CheckPlayOffIsGenerated(int p_Pk_Tournament)
    {

        try
        {
            DataTable oDataTable = DataBase.dt("SELECT Pk_Tournament FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString());

            if (oDataTable.Rows.Count > 1)
            {
                return true;
               
            }
            else
            {
                return false;
            }
        }
        catch (Exception Ex)
        {
            throw Ex;
        }

    }

    public static Boolean CheckPlayOffIsGeneratedWithScores(int p_Pk_Tournament)
    {
         
        try
        {
            DataTable oDataTable = DataBase.dt("SELECT Pk_Tournament FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " and MachineScore<>-1");

            if (oDataTable.Rows.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (Exception Ex)
        {
            throw Ex;
        }

    }

    public static Boolean DeleteMachineInPlayoffs(int p_Pk_Tournament, int p_Pk_Machine)
    { 
        OleDbConnection objConnection = new OleDbConnection();
        try
        {

            objConnection = DataBase.GetConnection();
            objConnection.Open();

            OleDbCommand objCommand =
            new OleDbCommand("DELETE * FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString() + " AND Fk_Machine=" + p_Pk_Machine.ToString(), objConnection);

            objCommand.ExecuteNonQuery();



            return true;

        }
        catch (Exception Ex)
        {
            throw;
        }
        finally
        {
            objConnection.Close();
        }

    }

    public static Boolean DeletePlayOff(int p_Pk_Tournament)
    {
        OleDbConnection objConnection = new OleDbConnection();
        try
        {

            objConnection = DataBase.GetConnection();
            OleDbCommand objCommand = new OleDbCommand("DELETE * FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString(), objConnection);
            objConnection.Open();
            objCommand.ExecuteNonQuery();


            return true;
        }
        catch (Exception Ex)
        {
            throw Ex;
        }
        finally
        {
            objConnection.Close();
        }


    }

    public static Boolean AddPlayoff(PlayoffRound oPlayoffRound)
    { //p_Rounds.Find(delegate(QualifyPlayersMachines t) { return t.Pk_Player  == 1; }); 
        OleDbConnection objConnection = new OleDbConnection();
        try
        {

            objConnection = DataBase.GetConnection();
            objConnection.Open();
            //OleDbCommand objCommandQuery =
            //        new OleDbCommand("SELECT * FROM PlayOffsTournamentRounds WHERE Fk_Machine=" + oPlayoffRound.Pk_Machine.ToString() +
            //                                                                 "AND Fk_Player=" + oPlayoffRound.Pk_Player.ToString() +
            //                                                                 "AND Pk_Tournament=" + oPlayoffRound.Pk_Tournament.ToString());

                     
            OleDbCommand objCommand =
                    new OleDbCommand("INSERT INTO PlayOffsTournamentRounds (Pk_Tournament,Fk_Machine,Round_Number,Fk_Player,MachineScore,Is_Joker,PlayInPosition,Player_Nick,Fk_Player_Zone,Machine_Acron,PlayerNumber,Machine_Number) VALUES (" +
                                      oPlayoffRound.Pk_Tournament.ToString() + "," +
                                      oPlayoffRound.Pk_Machine.ToString() + "," +
                                      oPlayoffRound.Round_Number.ToString() + "," +
                                      oPlayoffRound.Pk_Player.ToString() + "," +
                                      "-1" + "," + // -1 para inicializar
                                      "false" + "," + // aun no se juega el joker
                                      oPlayoffRound.PlayInPosition.ToString() + ",'" +
                                      oPlayoffRound.Player_Nick.ToString() + "'," +
                                      oPlayoffRound.Pk_Player_Zone.ToString() + ",'" +
                                      oPlayoffRound.Machine_Acron.ToString() + "'," +
                                      oPlayoffRound.PlayerNumber.ToString() + "," +
                                      oPlayoffRound.Machine_Number.ToString() +
                                      ")", objConnection);

                   

            objCommand.ExecuteNonQuery();



            return true;

        }
        catch (Exception Ex)
        {
            throw;
        }
        finally
        {
            objConnection.Close();
        }

    }

    public static Boolean SavePlayOff(List<PlayoffRound> p_Rounds)
    { //p_Rounds.Find(delegate(QualifyPlayersMachines t) { return t.Pk_Player  == 1; }); 
        OleDbConnection objConnection = new OleDbConnection();
        try
        {
            if (PlayoffRounds.CheckPlayOffIsGeneratedWithScores(p_Rounds[0].Pk_Tournament) == true)
            {
                return false;
            }
            //Controlamos si existia para borrarla
            if (PlayoffRounds.CheckPlayOffIsGenerated(p_Rounds[0].Pk_Tournament) == true)
            {
                Boolean res = PlayoffRounds.DeletePlayOff(p_Rounds[0].Pk_Tournament);
                if (res != true) {
                    return false;
                }
            }

            objConnection = DataBase.GetConnection();
            objConnection.Open();
            foreach (PlayoffRound oQualifyRound in p_Rounds)
            {
               
                    OleDbCommand objCommand =
                    new OleDbCommand("INSERT INTO PlayOffsTournamentRounds (Pk_Tournament,Fk_Machine,Round_Number,Fk_Player,MachineScore,Is_Joker,PlayInPosition,Player_Nick,Fk_Player_Zone,Machine_Acron,PlayerNumber,Machine_Number) VALUES (" +
                                      oQualifyRound.Pk_Tournament.ToString()  + "," +
                                      oQualifyRound.Pk_Machine.ToString() + "," +
                                      oQualifyRound.Round_Number.ToString() + "," +
                                      oQualifyRound.Pk_Player.ToString() + "," +
                                      "-1" + "," + // -1 para inicializar
                                      "false" + "," + // aun no se juega el joker
                                      oQualifyRound.PlayInPosition.ToString() + ",'" +
                                      oQualifyRound.Player_Nick.ToString() + "'," +
                                      oQualifyRound.Pk_Player_Zone.ToString() + ",'" +
                                      oQualifyRound.Machine_Acron.ToString() + "'," +
                                      oQualifyRound.PlayerNumber.ToString()  + "," +
                                      oQualifyRound.Machine_Number.ToString() +
                                      ")", objConnection);

                    objCommand.ExecuteNonQuery();
                
            }

            return true;

        }
        catch (Exception Ex)
        {
            throw Ex;
        }
        finally
        {
            objConnection.Close();
        }

    }

    public static List<int> GetDiferentPkMachinesForPlayoffRounds(int p_Pk_Tournament)
    {

        try
        {
            DataTable oDataTable = DataBase.dt("SELECT DISTINCT Fk_Machine FROM PlayOffsTournamentRounds WHERE Pk_Tournament=" + p_Pk_Tournament.ToString());
            List<int> PkMachines = new List<int>(); 
            
            foreach (DataRow iRow in oDataTable.Rows)
            {


                PkMachines.Add(Int32.Parse(iRow["Fk_Machine"].ToString()));


               

            }
            return PkMachines; 
        }
        catch (Exception Ex)
        {
            return null;
        }
    }

    public List<PlayoffRound> GetPlayOffRoundByRound(int p_RoundNumber)
    {

        return this._Rounds.FindAll(delegate(PlayoffRound p) { return p.Round_Number == p_RoundNumber; });

    }

    public List<PlayoffRound> GetPlayOffRoundByPlayer(int p_PlayerNumber)
    {

        return this._Rounds.FindAll(delegate(PlayoffRound p) { return p.PlayerNumber == p_PlayerNumber; });

    }

    public List<PlayoffRound> GetPlayOffRoundByMachine(int p_MachineNumber)
    {

        return this._Rounds.FindAll(delegate(PlayoffRound p) { return (p.Pk_Machine == p_MachineNumber && p.Score != -1); });

    }
 
    public List<PlayoffRound> GetPlayOffRoundByPlayerWithScore()
    {

        return this._Rounds.FindAll(delegate(PlayoffRound p) { return p.Score != -1; });

    }
  
    public List<PlayoffRound> GetAllPlayOffRounds()
    {

        return this._Rounds.FindAll(delegate(PlayoffRound p) { return p.Score != -2; });

    }
  
    public List<Machine> GetMachinesForPlayer(int p_Pk_Player) {
        List<PlayoffRound> oRounds = this._Rounds.FindAll(delegate(PlayoffRound p) { return p.Pk_Player == p_Pk_Player; });
        oRounds.Sort(new ObjectComparer<PlayoffRound>("Round_Number ASC, Machine_Number ASC", true));
        List<Machine> lMachines = new List<Machine>();
        foreach (PlayoffRound oRound in oRounds)
        {
            Machine oMachine = new Machine(oRound.Pk_Machine, "", oRound.Machine_Acron, Byte.Parse(oRound.Machine_Number.ToString()));
            lMachines.Add(oMachine);   
        }
        return lMachines; 
    }
  
    public List<Player> GetPlayersForTournament(int p_Pk_Tournament)
    {
        List<PlayoffRound> oRounds = this._Rounds.FindAll(delegate(PlayoffRound p) { return p.Pk_Tournament == p_Pk_Tournament; });
        oRounds.Sort(new ObjectComparer<PlayoffRound>("PlayerNumber ASC", true));
        List<Player> lPlayers = new List<Player>();
        if(oRounds.Count>0){  
        int PlayerNumber = -1; 
        foreach (PlayoffRound oRound in oRounds)
        {
            if(PlayerNumber != oRound.PlayerNumber){
                Player oPlayer = new Player(oRound.Pk_Player,"",oRound.Player_Nick,oRound.PlayerNumber,"",oRound.Pk_Player_Zone);
                lPlayers.Add(oPlayer);
            }
                PlayerNumber =oRound.PlayerNumber;
            
        }
        return lPlayers;
        }else{
            return null;
        }
    }
}

public class PlayoffRound{
    private int _Pk_Tournament;    
    private int _Pk_Player;   
    private string _Player_Nick;
    private int _Round_Number;
    private int _Pk_Player_Zone;
    private int _Pk_Machine;
    private string _Machine_Acron;
    private int _Machine_Number;
    private int _PlayInPosition;
    private Int64 _Score;
    private int _PointsInRound = 0;
    private int _PositionInRound = 0;
    private int _TotalPoints = 0;

    public int TotalPoints
    {
        get { return _TotalPoints; }
        set { _TotalPoints = value; }
    }

    public int PositionInRound
    {
        get { return _PositionInRound; }
        set { _PositionInRound = value; }
    }
    public int PointsInRound
    {
        get { return _PointsInRound; }
        set { _PointsInRound = value; }
    }

    private int _PlayerNumber;
    private Boolean _IsJoker;

    public Boolean IsJoker
    {
        get { return _IsJoker; }
        set { _IsJoker = value; }
    }
    public int PlayerNumber
    {
        get { return _PlayerNumber; }
        set { _PlayerNumber = value; }
    }    
    public int Pk_Tournament
    {
        get { return _Pk_Tournament; }
        set { _Pk_Tournament = value; }
    }
    public int Pk_Player
    {
        get { return _Pk_Player; }
        set { _Pk_Player = value; }
    }
    public string Player_Nick
    {
        get { return _Player_Nick; }
        set { _Player_Nick = value; }
    }
    public int Round_Number
    {
        get { return _Round_Number; }
        set { _Round_Number = value; }
    }
    public int Pk_Player_Zone
    {
        get { return _Pk_Player_Zone; }
        set { _Pk_Player_Zone = value; }
    }
    public int Pk_Machine
    {
        get { return _Pk_Machine; }
        set { _Pk_Machine = value; }
    }
    public string Machine_Acron
    {
        get { return _Machine_Acron; }
        set { _Machine_Acron = value; }
    }
    public int Machine_Number
    {
        get { return _Machine_Number; }
        set { _Machine_Number = value; }
    }
    public int PlayInPosition
    {
        get { return _PlayInPosition; }
        set { _PlayInPosition = value; }
    }
    public Int64 Score
    {
        get { return _Score; }
        set { _Score = value; }
    }

    public PlayoffRound(int p_Pk_Tournament,
                        int p_Pk_Player,   
                        string p_Player_Nick,                        
                        int p_Round_Number,
                        int p_Pk_Player_Zone,
                        int p_Pk_Machine,
                        string p_Machine_Acron,  
                        int p_Machine_Number,
                        int p_PlayInPosition,
                        Int64 p_Score,int p_Player_Number)
    {
        this._Machine_Number = p_Machine_Number;
        this._Machine_Acron = p_Machine_Acron;
        this._Pk_Machine = p_Pk_Machine;
        this._Pk_Player = p_Pk_Player;
        this._Pk_Player_Zone = p_Pk_Player_Zone;
        this._Pk_Tournament = p_Pk_Tournament;
        this._Player_Nick = p_Player_Nick;       
        this._PlayInPosition = p_PlayInPosition;
        this._Round_Number = p_Round_Number;
        this._Score = p_Score;
        this.PlayerNumber = p_Player_Number;
    
    }

    public PlayoffRound(int p_Pk_Tournament,
                    int p_Pk_Player,
                    string p_Player_Nick,
                    int p_Round_Number,
                    int p_Pk_Player_Zone,
                    int p_Pk_Machine,
                    string p_Machine_Acron,
                    int p_Machine_Number,
                    int p_PlayInPosition,
                    Int64 p_Score, int p_Player_Number, Boolean p_IsJoker)
    {
        this._Machine_Number = p_Machine_Number;
        this._Machine_Acron = p_Machine_Acron;
        this._Pk_Machine = p_Pk_Machine;
        this._Pk_Player = p_Pk_Player;
        this._Pk_Player_Zone = p_Pk_Player_Zone;
        this._Pk_Tournament = p_Pk_Tournament;
        this._Player_Nick = p_Player_Nick;
        this._PlayInPosition = p_PlayInPosition;
        this._Round_Number = p_Round_Number;
        this._Score = p_Score;
        this.PlayerNumber = p_Player_Number;
        this._IsJoker = p_IsJoker;

    } 
}